<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/11/7
 * Time: 14:12
 */

namespace app\api\service;


use app\common\model\ServerAuth;
use app\common\service\HostContact;
use app\common\service\ServerUpdate;
use app\common\service\ServerUpdateLog;
use app\common\service\ServerVersion;
use think\Db;

class ProductUpdate extends Base
{

    private $serverHostkey = 'a5t3ne4wc8fcf9e014du47f4ke0f22d8';

    /**
     * @name 同时在线下载数
     * @param int $limit
     * @author wx
     * @date 2019/11/7 14:44
     */
    function online($limit = 200)
    {
        $count = db('server_update')->where('status',1)->count();
        if ($limit > $count) {
            return true;
        }else{
            return false;
        }
    }

    /**
     * @name 返回更新包路径
     * @param $data
     * @return bool|mixed
     * @author wx
     * @date 2019/11/7 16:46
     */
    function getPackagePath($data)
    {
        //判断超时
        $this->timeOut(60*60);

        //1. 检查同时下载客户端数量
        $online = $this->online(200);
        if(!$online){
            $this->setError($this->CODE_FAIL, '同时下载数量已达上限,请等待!');
            return '同事下载数量达到上限';
        }



        if(empty($data)){
            $this->setError($this->CODE_FAIL, '参数错误!');
            return false;
        }
        //1. 数据校验
        $checkArr = array('os', 'type', 'hostkey');

        foreach ($checkArr as $k => $v){
            if(!isset($data[$v]) ){
                $this->setError($this->CODE_FAIL, $v.'为必须参数');
                return $v.'为必须参数';
            }
        }

        //验证客户端授权是否到期
        $hostInfo = db('host h')->where('key', $data['hostkey'])->find();

        if(!$hostInfo){
            $this->setError($this->CODE_FAIL,'未查询到该主机');

            return '未查询到该主机';
        }

        $moduleTime = db('server_auth_module')->where('module_key', 'client')->find();

        if (!$moduleTime) {
            $this->setError($this->CODE_FAIL, '未查询到客户端授权信息');
            return '未查询到客户端授权信息';
        }

        $authServer = new \app\adminapiv3\service\ServerAuth();
        $systemTime = $authServer->getSystemTime();

        if($moduleTime['etime'] != 0){
            if ($moduleTime['etime'] - $systemTime < 0) {
                $this->setError($this->CODE_FAIL,'该主机授权已到期,暂不支持更新');

                return '该主机授权已到期,暂不支持更新';
            }
        }

        //查询更新包数据
        $list = db('server_update_list')
            ->where('type', strtolower($data['type']))
            ->where('os', strtolower($data['os']))
            ->group('type, version')
            ->select();

        $dataP = [];
        foreach ($list as $k => $v){
            $dataP[$k] = db('server_update_list')
                ->where('type', $v['type'])
                ->where('version', $v['version'])
                ->order('id','desc')
                ->find();
        }


        $urlHeader = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/';//协议头

        $jsonArr = array();
        foreach ($dataP as $k => $v){
            $v['url'] = substr($v['url'], strpos($v['url'],'public/') + strlen('public/'));
            if (file_exists($v['url'])) {
                $jsonArr[$k]['hash'] = $v['hash'];
                $jsonArr[$k]['url'] = $urlHeader.$v['url'];
                $jsonArr[$k]['name'] = $v['name'];
                $jsonArr[$k]['version'] = $v['version'];
                $jsonArr[$k]['ext'] = $v['ext'];
                $jsonArr[$k]['desc'] = $v['desc'];
            }
        }

        if(empty($jsonArr)){
            $this->setError($this->CODE_FAIL, '当前已是最新版本');
            return '当前已是最新版本';
        }

        //3. 添加数据到系统更新表中
        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip

        $server = new ServerUpdate();
        $data_info = $server->findData(['ip' => $ip]);
        if($data_info){
            $updateData = array(
                'status' => 1,
                'last_time' => time(),
            );
            $server->modify(['id' => $data_info['id']], $updateData);
        }else{
            $addData = array(
                'ip' => $ip,
                'status' => 1,
                'last_time' => time(),
                'ctime' => time(),
            );
            $server->add($addData);
        }

        //4. 返回数据
        return $jsonArr;
    }


    /**
     * @name 客户端更新包下载结果
     * @param $data
     * @return bool
     * @author wx
     * @date 2019/11/7 16:47
     */
    function downloadResult($data)
    {
//        $data['desc'] = 1;
//        $data['result'] = 3;
//        $data['new_version'] = 3.1;
//        $data['old_version'] = 3.0;
//        $data['os'] = 1;
//        $data['hostkey'] = $this->serverHostkey;
//
//        echo json_encode($data);die;
        $fileLog = '../runtime/log/ServerUpdate.log';
        $params = $_SERVER['REMOTE_ADDR'].'下载结果:'.date('Y-m-d H:i:s',time()).PHP_EOL.json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL;
        file_put_contents($fileLog,$params,FILE_APPEND);

        //1. 数据校验
        $checkArr = array('old_version', 'new_version', 'os', 'result','desc', 'hostkey');

        foreach ($checkArr as $k => $v){
            if(!isset($data[$v]) ){
                $this->setError($this->CODE_FAIL, $v.'为必须参数');
                return false;
            }
        }

        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip

        //2. 判断下载结果 下载成功不记录日志,失败才记录
        $downloadRes = $data['result'];
        if($downloadRes == 3){//下载失败,记录更新日志

            $host_id = db('host')->where('key', $data['hostkey'])->value('id');

            if($host_id === null){
                $this->setError($this->CODE_FAIL, '未查询到该主机');
                return false;
            }

            //添加系统更新日志
            $updateServer = new ServerUpdateLog();
            $add_update_log = array(
                'old_version' => $data['old_version'],
                'new_version' => $data['new_version'],
                'ip' => $ip,
                'host_id' => $host_id,
                'type' => $host_id == 1 ? 1 : 2,
                'status' => $downloadRes,
                'desc' => $data['desc'],
                'ctime' => time()
            );
            $updateServer->add($add_update_log);
        }


        //3. 修改下载任务表
        $server = new ServerUpdate();
        $server->modify(['ip' => $ip], ['status' => $downloadRes]);

        return 'success';
    }

    /**
     * @name 客户端更新包执行结果
     * @author wx
     * @date 2019/11/7 16:52
     */
    function updateResult($data)
    {
        //1. 验证数据
//        $data['old_version'] = 3.0;
//        $data['new_version'] = 3.1;
//        $data['desc'] = '1223';
//        $data['result'] = 2;
//        $data['hostkey'] = '@serverupdate';
//        $data['type'] = 1;

        //echo json_encode($data);die;


        $fileLog = '../runtime/log/ServerUpdate.log';
        $params = $_SERVER['REMOTE_ADDR'].'更新结果:'.date('Y-m-d H:i:s',time()).PHP_EOL.json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL;
        file_put_contents($fileLog,$params,FILE_APPEND);

        //type 1=> 客户端 2 => 服务端
        $check_a = ['old_version', 'new_version', 'desc', 'result', 'hostkey', 'type'];
        foreach ( $check_a as $v)
        {
            if(!isset($data[$v]))
            {
                $this->setError($this->CODE_FAIL, $v.'为必要参数');
                return false;
            }
        }

        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip

        //服务端
        $host_id = db('host')->where('key', $data['hostkey'])->value('id');

        if($host_id === null){
            $this->setError($this->CODE_FAIL, '未查询到该主机');
            return false;
        }

        //2. 添加系统更新日志
        $update_server = new ServerUpdateLog();
        $add_update_log = array(
            'old_version' => $data['old_version'],
            'new_version' => $data['new_version'],
            'ip' => $ip,
            'host_id' => $host_id,
            'type' => $data['type'],
            'status' => $data['result'],
            'desc' => $data['desc'],
            'ctime' => time()
        );

        $update_server->add($add_update_log);

        //更新版本号
        db('host')->where('id', $host_id)->update([
            'client_version' => $data['new_version'],
            'client_update_status' => $data['result'],
        ]);
        return 'success';
    }

    function timeOut($expires_time = 600)
    {
        $data = Db::name('server_update')->where('status',1)->select();

        $updateStatus = [];
        foreach ($data as $k => $v){
            if ($v['last_time'] + $expires_time < time()) {
                $updateStatus[] = $v['id'];
            }
        }

        if($updateStatus){//修改状态
            Db::name('server_update')->whereIn('id', $updateStatus)->update(['status' => 4]);
        }
    }
}